﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace WebRole1
{
    public class MEFContext
    {
        public const string CONTAINER_NAME = "resources";
        static public CompositionContainer MEFContainer {get;set;}
        static public string CacheFolderPath { get; set; }

        static MEFContext()
        {
            //just to facilitate the lock later
            MEFContainer = new CompositionContainer();
        }

        public static void InitializeContainer()
        {
            //pull the files from storage into the  local directory
            UpdateFromStorage();
            //build the container from the local directory
            BuildContainer();
        }

        public static void BuildContainer()
        {
            // store the container for later use (resolve type instances)
            var catalog = new DirectoryCatalog(CacheFolderPath);
            CompositionContainer newContainer = new CompositionContainer(catalog);
            newContainer.ComposeParts();
            
            lock(MEFContainer)
            {
                MEFContainer = newContainer;
            }

        }

        public static void UpdateCatalog()
        {
            UpdateFromStorage();
            BuildContainer();
        }

        public static void UpdateFromStorage()
        {
            // could also pull from config, etc.
            string containerName = CONTAINER_NAME;

            // using development storage account
            CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

            // create the blob client and use it to create the container object
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // note that here is where the container name is passed in order to get to the files we want
            CloudBlobContainer blobContainer = new CloudBlobContainer(storageAccount.BlobEndpoint.ToString() + "/" + containerName, blobClient);

            // create the options needed to get the blob list
            BlobRequestOptions options = new BlobRequestOptions();
            options.AccessCondition = AccessCondition.None;
            options.BlobListingDetails = BlobListingDetails.All;
            options.UseFlatBlobListing = true;
            options.Timeout = new TimeSpan(0, 1, 0);

            // retrieve the list of files/blobs in the container.  There are ways to fetch by prefix, but in this instance we want them all
            System.Collections.Generic.IEnumerable<IListBlobItem> blobs = blobContainer.ListBlobs(options);

            // iterate over the collect. grab the files and save them locally.
            foreach (IListBlobItem item in blobs)
            {
                // raw path: \Resources%2fdevstoreaccount1%2fresources%2fbusinesscommon.dll'
                string fileAbsPath = item.Uri.AbsolutePath.ToLower();
                // just want the file name...
                fileAbsPath = fileAbsPath.Substring(fileAbsPath.LastIndexOf('/') + 1);

                try
                {
                    Microsoft.WindowsAzure.StorageClient.CloudPageBlob pageblob = new CloudPageBlob(item.Uri.ToString());
                    pageblob.DownloadToFile(MEFContext.CacheFolderPath + fileAbsPath, options);
                }
                catch (Exception)
                {
                    // Ignore exceptions, if we can't write it's because we've already got the file, move on
                }
            }
        }



    }
}